function class_extends(ctor, base) {
	ctor.prototype = new base();
	ctor.prototype.constructor = ctor;
}

function table_column(key, label) {
	this.key = key;
	this.label = label;
	this.formatter = null;
}

// base class
function table_data() {
	this.columns = [];
	// json array [{}]
	this.rows = [];
	var that = this;
	
	this.add_column = function(col) {
		if (!this.columns) {
			this.columns = [];
		}
		this.columns.push(col);
	};
	
	this.add_column_with_parm = function(key, label, formatter) {
		if (!key || !label) {
			return;
		}
		var col = new table_column(key, label);
		if (!formatter) {
			col.formatter = formatter;
		}
		this.add_column(col);
	};
	
	this.add_row = function(row) {
		if (!this.rows) {
			this.rows = [];
		}
		this.rows.push(row);
	};
	
	this.remove_all_rows = function() {
		this.rows = [];
	};
	
	this.get_table_html = function() {
		var table;
		table = "<table>";
		table += get_thead_html();
		table += get_tbody_html();
		table += "</table>";
		return table;
	};
	
	this.get_data = function(col, row) {
		var formatter = col.formatter;
		if (formatter) {
			return formatter.call(null, row[col.key]);
		} else {
			return row[col.key];
		}
	};
	
	this.export_csv = function() {
		var that = this;
		var col_delim = ',';
		var row_delim = '\r\n';
		var csv = '';
		// header
		csv += this.columns.map(function(col) {
			return col.label;
		}).join(col_delim) + row_delim;
		
		// body
		csv += this.rows.map(function(row) {
			return that.columns.map(function(col) {
				return row[col.key];
			}).join(col_delim);
		}).join(row_delim);
		
		csv += row_delim;
		csv += row_delim;
		return csv;
	};
	
	var get_thead_html = function() {
		var thead;
		thead = "<thead><tr class='ui-state-default'>";
		for (var i = 0; i < that.columns.length; i++) {
			thead += "<td>" + that.columns[i].label + "</td>";
		}
		thead += "</tr></thead>";
		return thead;
	};
	
	var get_tbody_html = function() {
		var tbody;
		tbody = "<tbody>";
		for (var i = 0; i < that.rows.length; i++) {
			tbody += get_tr_html(that.rows[i]);
		}
		tbody += "</tbody>";
		return tbody;
	};
	
	var get_tr_html = function(row) {
		var tr;
		var col_name;
		tr = "<tr>";
		for (var i = 0; i < that.columns.length; i++) {
			col_key = that.columns[i].key;
			tr += get_td_html(row[col_key]);
		}
		tr += "</tr>";
		return tr;
	};
	
	var get_td_html = function(data) {
		return "<td>" + data + "</td>";
	};
}

function web_data() {
	table_data.call(this);
	
	var that = this;
	
	(function() {
		that.add_column_with_parm("url", "URL");
		that.add_column_with_parm("elapsed", "Elapsed");
		that.add_column_with_parm("startTime", "StartTime");
		that.add_column_with_parm("transTime", "TransTime");
		// this.add_column_with_parm("url", "To First Byte");
		// this.add_column_with_parm("url", "To Last Byte");
	})();
	
	// TODO: own method
	
}

class_extends(web_data, table_data);

function isrvr_data() {
	table_data.call(this);
	
	var that = this;
	
	(function() {
		that.add_column_with_parm("url", "URL");
		that.add_column_with_parm("elapsed", "Elapsed");
		that.add_column_with_parm("startTime", "StartTime");
		that.add_column_with_parm("transTime", "TransTime");
	})();
	
	// TODO: own method
}

class_extends(isrvr_data, table_data);

function rsrc_data() {
	table_data.call(this);
	
	var that = this;
	
	(function() {
		that.add_column_with_parm("id", "ID");
		that.add_column_with_parm("url", "URL");
		that.add_column_with_parm("method", "Method");
		that.add_column_with_parm("startTime", "StartTime");
		that.add_column_with_parm("requestTime", "RequestTime(ms)");
		that.add_column_with_parm("responseStartTime", "ResponseStartTime");
		that.add_column_with_parm("responseTime", "ResponseTime(ms)");
		that.add_column_with_parm("endTime", "EndTime");
		that.add_column_with_parm("totalTime", "TotalTime(ms)");
		that.add_column_with_parm("blocked", "Blocked(ms)");
		that.add_column_with_parm("totalBytes", "TotalBytes(bytes)");
		that.add_column_with_parm("mimeType", "MimeType");
		that.add_column_with_parm("statusCode", "StatusCode");
		that.add_column_with_parm("fromCache", "FromCache");
	})();
	
	// TODO: own method
}

class_extends(rsrc_data, table_data);

function js_data() {
	table_data.call(this);
	
	var that = this;
	
	(function() {
		that.add_column_with_parm("startTime", "StartTime");
		that.add_column_with_parm("duration", "Duration");
		that.add_column_with_parm("scriptName", "ScriptName");
		that.add_column_with_parm("scriptLine", "ScriptLine");
		
		/*
		that.add_column_with_parm("function", "Function");
		that.add_column_with_parm("fileName", "File Name");
		that.add_column_with_parm("startLine", "Start Line");
		that.add_column_with_parm("endLine", "End Line");
		that.add_column_with_parm("callCount", "Call Count");
		that.add_column_with_parm("totalOwn", "Total Own");
		that.add_column_with_parm("minOwn", "Min Own");
		that.add_column_with_parm("maxOwn", "Max Own");*/
	})();
	
	// TODO: own method
}

class_extends(js_data, table_data);
